#include "sys_ctrl_mgr_imp.h"
#include "vi_mgr.h"
#include "vpss_mgr.h"
#include "avs_mgr.h"
#include "vo_mgr.h"
#include "venc_mgr.h"
#include "pciv_mgr.h"
#include "aenc_mgr.h"
#include "ai_mgr.h"
#include "config_manager.h"
#include "guard.h"

#include "hi_comm_sys.h"
#include "hi_buffer.h"
#include "mpi_sys.h"
#include "mpi_vb.h"

#include <stdio.h>

using namespace Json;
using namespace detu_config_manager;
using namespace detu_infra;

namespace detu_media
{

#define MEDIA_SYSTEM_CONTROL_CONFIG_NAME "media.systemControl"

PATTERN_SINGLETON_IMPLEMENT(SysCtrlMgrImp)

SysCtrlMgrImp::SysCtrlMgrImp(void)
    : SysCtrlMgr(), fStarted(false), fMutex(MUTEX_RECURSIVE)
{
    memset(&fSupplementConf, 0, sizeof(VB_SUPPLEMENT_CONFIG_S));
    memset(&fVbConf, 0, sizeof(VB_CONFIG_S));
}

SysCtrlMgrImp::~SysCtrlMgrImp(void)
{
    if (isStarted())
        stop();
}

S_Result SysCtrlMgrImp::start(void)
{
    Guard guard(fMutex);
    if (isStarted())
        stop();

    fStarted = true;

    S_Result ret = S_ERROR;
    do
    {
        ConfigManager& cfgMgr = *ConfigManager::instance();
        Value sysCtrlCfg, resp;
        if (S_OK != cfgMgr.getConfig(MEDIA_SYSTEM_CONTROL_CONFIG_NAME, sysCtrlCfg, resp))
        {
            printf("get media system control config failed! resp: \n%s\n", resp.toStyledString().c_str());
            break;
        }

        if (sysCtrlCfg.isMember("vb"))
        {
            const Value& vbConfig = sysCtrlCfg["vb"];
            if (S_OK != initVb(vbConfig))
            {
                printf("init vb failed!\n");
                break;
            }

            if (S_OK != initSystem())
            {
                printf("init system failed!\n");
                deInitVb();
                break;
            }
            ret = S_OK;
        }

    }
    while(0);

    return ret;
}

S_Result SysCtrlMgrImp::stop(void)
{

    Guard guard(fMutex);

    deInitSystem();
    deInitVb();

    fStarted = false;

    return S_OK;
}

bool SysCtrlMgrImp::isStarted(void)
{
    return fStarted;
}

S_Result SysCtrlMgrImp::setViVpssMode(const Json::Value& config)
{
    Guard guard(fMutex);
    VI_VPSS_MODE_S      stVIVPSSMode = {VI_OFFLINE_VPSS_OFFLINE, VI_OFFLINE_VPSS_OFFLINE,
        VI_OFFLINE_VPSS_OFFLINE, VI_OFFLINE_VPSS_OFFLINE,
        VI_OFFLINE_VPSS_OFFLINE, VI_OFFLINE_VPSS_OFFLINE,
        VI_OFFLINE_VPSS_OFFLINE, VI_OFFLINE_VPSS_OFFLINE};
    HI_S32 s32Ret = HI_MPI_SYS_SetVIVPSSMode(&stVIVPSSMode);

    if (HI_SUCCESS != s32Ret)
    {
        printf("Set VI-VPSS mode Param failed with %#x!\n", s32Ret);
    }

    return (s32Ret == HI_SUCCESS) ? S_OK : S_ERROR;
}

S_Result SysCtrlMgrImp::bind(const Json::Value& config)
{
    Guard guard(fMutex);
    S_Result ret = S_ERROR;
    do
    {
        MPP_CHN_S src, dst;

        if (config.isMember("dst"))
        {
            const Value& dstCfg = config["dst"];
            if (S_OK != getDstIdByName(dstCfg, dst))
            {
                printf("get dst ID failed!\n");
                break;
            }
        }
        else
        {
            printf("no dst config!\n");
            break;
        }

        if (config.isMember("src"))
        {
            const Value& srcCfg = config["src"];
            if (S_OK != getSrcIdByName(srcCfg, src))
            {
                printf("get src ID failed!\n");
                break;
            }

            if (S_OK != startSrc(srcCfg))
            {
                printf("startSrc failed!\n");
                break;
            }
        }
        else
        {
            printf("no src config!\n");
            break;
        }
		
        HI_S32 s32Ret = HI_MPI_SYS_Bind(&src, &dst);
        if (HI_SUCCESS != s32Ret)
        {
            printf("bind failed with ret: %#x! src: mod %d, dev: %d, chn: %d; dst: mod %d, dev: %d, chn: %d.\n", s32Ret, src.enModId, src.s32DevId, src.s32ChnId, dst.enModId, dst.s32DevId, dst.s32ChnId);
            const Value& srcCfg = config["src"];
            if (S_OK != stopSrc(srcCfg));
            {
                printf("stopSrc failed!\n");
                break;
            }
            break;
        }

        ret = S_OK;
    }
    while(0);

    return ret;
}

S_Result SysCtrlMgrImp::unbind(const Json::Value& config)
{
    Guard guard(fMutex);
    S_Result ret = S_ERROR;
    do
    {
        MPP_CHN_S src, dst;

        if (config.isMember("dst"))
        {
            const Value& dstCfg = config["dst"];
            if (S_OK != getDstIdByName(dstCfg, dst))
            {
                printf("get dst ID failed!\n");
                break;
            }
        }
        else
        {
            printf("no dst config!\n");
            break;
        }

        if (config.isMember("src"))
        {
            const Value& srcCfg = config["src"];
            if (S_OK != getSrcIdByName(srcCfg, src))
            {
                printf("get src ID failed!\n");
                break;
            }
        }
        else
        {
            printf("no src config!\n");
            break;
        }

        HI_S32 s32Ret = HI_MPI_SYS_UnBind(&src, &dst);
        if (HI_SUCCESS != s32Ret)
        {
            printf("unbind failed with ret: %d! src: mod %d, dev: %d, chn: %d; dst: mod %d, dev: %d, chn: %d.\n", s32Ret, src.enModId, src.s32DevId, src.s32ChnId, dst.enModId, dst.s32DevId, dst.s32ChnId);
            break;
        }

        const Value& srcCfg = config["src"];
        if (S_OK != stopSrc(srcCfg))
        {
            printf("stopSrc failed!\n");
            break;
        }

        ret = S_OK;
    }
    while(0);

    return ret;
}

S_Result SysCtrlMgrImp::mmzAlloc(Uint64_t* pu64PhyAddr, void** ppVirAddr,
                              const char* pstrMmb, const char* pstrZone, Uint32_t u32Len)
{
    Guard guard(fMutex);
    HI_S32 s32Ret = HI_MPI_SYS_MmzAlloc(pu64PhyAddr, ppVirAddr, pstrMmb, pstrZone, u32Len);
    printf("pu64PhyAddr: %#x, u64PhyAddr: %#x\n", pu64PhyAddr, *pu64PhyAddr);
    if (HI_SUCCESS != s32Ret)
        printf("HI_MPI_SYS_MmzAlloc failed! ret: %#x\n", s32Ret);

    return (HI_SUCCESS == s32Ret) ? S_OK : S_ERROR;
}

S_Result SysCtrlMgrImp::mmzFree(Uint64_t u64PhyAddr, void* pVirAddr)
{
  Guard guard(fMutex);
  HI_S32 s32Ret = HI_MPI_SYS_MmzFree(u64PhyAddr, pVirAddr);
  if (HI_SUCCESS != s32Ret)
      printf("HI_MPI_SYS_MmzFree failed! ret: %#x\n", s32Ret);

  return (HI_SUCCESS == s32Ret) ? S_OK : S_ERROR;
}

S_Result SysCtrlMgrImp::initVb(const Json::Value& config)
{
    Guard guard(fMutex);
    S_Result ret = S_ERROR;
    do
    {
        HI_S32 s32Ret = HI_SUCCESS;
        fSupplementConf.u32SupplementConfig = (config.isMember("supplementConfig") && config["supplementConfig"].isIntegral()) ? config["supplementConfig"].asUInt() : 1u;

        printf("u32SupplementConfig: %u\n", fSupplementConf.u32SupplementConfig);

        s32Ret = HI_MPI_VB_SetSupplementConfig(&fSupplementConf);

        if (HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_VB_SetSupplementConf failed! ret: 0x%x\n", s32Ret);
            break;
        }

        fVbConf.u32MaxPoolCnt = (config.isMember("maxPoolCount") && config["maxPoolCount"].isIntegral()) ? config["maxPoolCount"].asUInt() : 128u;
        printf("u32MaxPoolCnt: %u\n", fVbConf.u32MaxPoolCnt);

        if (config.isMember("commonPools"))
        {
            const Value& commonPools = config["commonPools"];

            int poolIndex = 0;

            //avs pool
            if (commonPools.isMember("AVS"))
            {
                const Value& pool = commonPools["AVS"];

                Uint32_t width = (pool.isMember("width") && pool["width"].isIntegral()) ? pool["width"].asUInt()         : 3936u;
                Uint32_t height = (pool.isMember("height") && pool["height"].isIntegral()) ? pool["height"].asUInt()     : 2768u;
                Uint32_t count = (pool.isMember("count") && pool["count"].isIntegral()) ? pool["count"].asUInt()         : 64u;

                fVbConf.astCommPool[poolIndex].u64BlkSize = AVS_GetPicBufferSize(width, height, COMPRESS_MODE_TILE, DEFAULT_ALIGN);
                fVbConf.astCommPool[poolIndex].u32BlkCnt = count;
                printf("poolName: %s, poolIndex: %d, width: %u, height: %u, u64BlkSize: %llu, count, %u\n", "AVS", poolIndex, width, height, fVbConf.astCommPool[poolIndex].u64BlkSize, count);

                poolIndex++;
            }

            //VIRaw pool
            if (commonPools.isMember("VIRaw"))
            {
                const Value& pool = commonPools["VIRaw"];

                Uint32_t width = (pool.isMember("width") && pool["width"].isIntegral()) ? pool["width"].asUInt()         : 3936u;
                Uint32_t height = (pool.isMember("height") && pool["height"].isIntegral()) ? pool["height"].asUInt()     : 2768u;
                Uint32_t count = (pool.isMember("count") && pool["count"].isIntegral()) ? pool["count"].asUInt()         : 64u;

                fVbConf.astCommPool[poolIndex].u64BlkSize = VI_GetRawBufferSize(width, height, PIXEL_FORMAT_RGB_BAYER_16BPP,
                                         COMPRESS_MODE_LINE, DEFAULT_ALIGN);
                fVbConf.astCommPool[poolIndex].u32BlkCnt = count;
                printf("poolName: %s, poolIndex: %d, width: %u, height: %u, u64BlkSize: %llu, count, %u\n", "VIRaw", poolIndex, width, height, fVbConf.astCommPool[poolIndex].u64BlkSize, count);

                poolIndex++;
            }

            //common pools
            if (commonPools.isMember("common"))
            {
                const Value& common = commonPools["common"];
                for(ValueConstIterator iter = common.begin(); iter != common.end(); iter++)
                {
                    const Value& pool = *iter;

                    Uint32_t width = (pool.isMember("width") && pool["width"].isIntegral()) ? pool["width"].asUInt()         : 3936u;
                    Uint32_t height = (pool.isMember("height") && pool["height"].isIntegral()) ? pool["height"].asUInt()     : 2768u;
                    Uint32_t count = (pool.isMember("count") && pool["count"].isIntegral()) ? pool["count"].asUInt()         : 64u;

                    fVbConf.astCommPool[poolIndex].u64BlkSize = COMMON_GetPicBufferSize(width, height,
                                             PIXEL_FORMAT_YVU_SEMIPLANAR_420, DATA_BITWIDTH_12, COMPRESS_MODE_NONE, DEFAULT_ALIGN);
                    fVbConf.astCommPool[poolIndex].u32BlkCnt = count;
                    printf("poolName: %s, poolIndex: %d, width: %u, height: %u, u64BlkSize: %llu, count, %u\n", iter.name().c_str(), poolIndex, width, height, fVbConf.astCommPool[poolIndex].u64BlkSize, count);

                    poolIndex++;
                }
            }
        }

        s32Ret = HI_MPI_VB_SetConfig(&fVbConf);

        if (HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_VB_SetConf failed! ret: 0x%x\n", s32Ret);
            break;
        }

        s32Ret = HI_MPI_VB_Init();

        if (HI_SUCCESS != s32Ret)
        {
            printf("HI_MPI_VB_Init failed! ret: 0x%x\n", s32Ret);
            break;
        }

        ret = S_OK;

    }
    while(0);

    return ret;
}

S_Result SysCtrlMgrImp::deInitVb(void)
{
    Guard guard(fMutex);
    HI_S32 s32Ret = HI_MPI_VB_Exit();

    if (HI_SUCCESS != s32Ret)
    {
        printf ("HI_MPI_VB_Exit failed! ret: 0x%x\n", s32Ret);
    }
    printf ("HI_MPI_VB_Exit OK! \n");


    memset(&fSupplementConf, 0, sizeof(VB_SUPPLEMENT_CONFIG_S));
    memset(&fVbConf, 0, sizeof(VB_CONFIG_S));

    return (s32Ret == HI_SUCCESS) ? S_OK : S_ERROR;
}

S_Result SysCtrlMgrImp::initSystem(void)
{
    Guard guard(fMutex);
    HI_S32 s32Ret = HI_MPI_SYS_Init();

    if (HI_SUCCESS != s32Ret)
    {
        printf ("HI_MPI_SYS_Init failed! ret: 0x%x\n", s32Ret);
    }

    return (s32Ret == HI_SUCCESS) ? S_OK : S_ERROR;
}

S_Result SysCtrlMgrImp::deInitSystem(void)
{
    Guard guard(fMutex);
    HI_S32 s32Ret = HI_MPI_SYS_Exit();

    if (HI_SUCCESS != s32Ret)
    {
        printf ("HI_MPI_SYS_Exit failed! ret: 0x%x\n", s32Ret);
    }

    return (s32Ret == HI_SUCCESS) ? S_OK : S_ERROR;
}

S_Result SysCtrlMgrImp::getSrcIdByName(const Json::Value& config, MPP_CHN_S& id)
{
    Guard guard(fMutex);
    S_Result ret = S_ERROR;

    do
    {
        if (config.isMember("modName") && config["modName"].isString())
        {
            const std::string& modName = config["modName"].asString();
            if (0 == modName.compare("vi"))
            {
                id.enModId = HI_ID_VI;
                ViMgr& viMgr = *ViMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    ViPipe* viPipe = NULL;
                    if (S_OK != viMgr.getPipe(devName, &viPipe))
                    {
                        printf("get vi pipe: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != viPipe->getId(id.s32DevId))
                    {
                        printf("get vi pipe: %s Id failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        ViChn* viChn = NULL;
                        if (S_OK != viPipe->getChn(chnName, &viChn))
                        {
                            printf("get vi chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != viChn->getId(id.s32ChnId))
                        {
                            printf("get vi chn: %s Id failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                    else
                        printf("src chnName not exist!\n");
                }
                else
                    printf("src devName not exist!\n");
            }
            else if (0 == modName.compare("vpss"))
            {
                id.enModId = HI_ID_VPSS;
                VpssMgr& vpssMgr = *VpssMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    VpssGrp* vpssGrp = NULL;
                    if (S_OK != vpssMgr.getGrp(devName, &vpssGrp))
                    {
                        printf("get vpss grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != vpssGrp->getId(id.s32DevId))
                    {
                        printf("get vpss grp: %s Id failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        VpssChn* vpssChn = NULL;
                        if (S_OK != vpssGrp->getChn(chnName, &vpssChn))
                        {
                            printf("get vpss chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != vpssChn->getId(id.s32ChnId))
                        {
                            printf("get vpss chn: %s Id failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                    else
                        printf("src chnName not exist!\n");
                }
                else
                    printf("src devName not exist!\n");
            }
            else if (0 == modName.compare("avs"))
            {
                id.enModId = HI_ID_AVS;
                AvsMgr& avsMgr = *AvsMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    AvsGrp* avsGrp = NULL;
                    if (S_OK != avsMgr.getGrp(devName, &avsGrp))
                    {
                        printf("get avs grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != avsGrp->getId(id.s32DevId))
                    {
                        printf("get avs grp: %s Id failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        AvsChn* avsChn = NULL;
                        if (S_OK != avsGrp->getChn(chnName, &avsChn))
                        {
                            printf("get avs chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != avsChn->getId(id.s32ChnId))
                        {
                            printf("get avs chn: %s Id failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                    else
                        printf("src chnName not exist!\n");
                }
                else
                    printf("src devName not exist!\n");
            }
            else if (0 == modName.compare("pciv"))
            {
                id.enModId = HI_ID_PCIV;
                PcivMgr& pcivMgr = *PcivMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    PcivChip* pcivChip = NULL;
                    if (S_OK != pcivMgr.getChip(devName, &pcivChip))
                    {
                        printf("get pciv chip: %s failed!\n", devName.c_str());
                        break;
                    }

					id.s32DevId = 0;

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        PcivChn* pcivChn = NULL;
                        if (S_OK != pcivChip->getChn(chnName, &pcivChn))
                        {
                            printf("get pciv chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != pcivChn->getId(id.s32ChnId))
                        {
                            printf("get pciv chn: %s Id failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                    else
                        printf("src chnName not exist!\n");
                }
                else
                    printf("src devName not exist!\n");
            }
            else if(0 == modName.compare("ai"))
            {
                id.enModId = HI_ID_AI;

                AiMgr& aiMgr = *AiMgr::instance();

                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    AiDev* aiDev = NULL;
                    if (S_OK != aiMgr.getDev(devName, &aiDev))
                    {
                        printf("get ai dev: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != aiDev->getId(id.s32DevId))
                    {
                        printf("get ai dev: %s Id failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        AiChn* aiChn = NULL;
                        if (S_OK != aiDev->getChn(chnName, &aiChn))
                        {
                            printf("get ai chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != aiChn->getId(id.s32ChnId))
                        {
                            printf("get ai chn: %s Id failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                    else
                        printf("src chnName not exist!\n");
                }
                else
                    printf("src devName not exist!\n");

            }
        }
        else
            printf("src modName not exist!\n");
    }
    while(0);

    return ret;
}

S_Result SysCtrlMgrImp::getDstIdByName(const Json::Value& config, MPP_CHN_S& id)
{
    Guard guard(fMutex);
    S_Result ret = S_ERROR;

    do
    {
        if (config.isMember("modName") && config["modName"].isString())
        {
            const std::string& modName = config["modName"].asString();
            if (0 == modName.compare("vpss"))
            {
                id.enModId = HI_ID_VPSS;
                VpssMgr& vpssMgr = *VpssMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    VpssGrp* vpssGrp = NULL;
                    if (S_OK != vpssMgr.getGrp(devName, &vpssGrp))
                    {
                        printf("get vpss grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != vpssGrp->getId(id.s32DevId))
                    {
                        printf("get vpss grp: %s Id failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        VpssPipe* vpssPipe = NULL;
                        if (S_OK != vpssGrp->getPipe(chnName, &vpssPipe))
                        {
                            printf("get vpss pipe: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != vpssPipe->getId(id.s32ChnId))
                        {
                            printf("get vpss pipe: %s Id failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                    else
                        printf("dst chnName not exist!\n");
                }
                else
                    printf("dst devName not exist!\n");
            }
            else if (0 == modName.compare("avs"))
            {
                id.enModId = HI_ID_AVS;
                AvsMgr& avsMgr = *AvsMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    AvsGrp* avsGrp = NULL;
                    if (S_OK != avsMgr.getGrp(devName, &avsGrp))
                    {
                        printf("get avs grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != avsGrp->getId(id.s32DevId))
                    {
                        printf("get avs grp: %s Id failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        AvsPipe* avsPipe = NULL;
                        if (S_OK != avsGrp->getPipe(chnName, &avsPipe))
                        {
                            printf("get avs pipe: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != avsPipe->getId(id.s32ChnId))
                        {
                            printf("get avs pipe: %s Id failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                    else
                        printf("dst chnName not exist!\n");
                }
                else
                    printf("dst devName not exist!\n");
            }
            else if (0 == modName.compare("pciv"))
            {
                id.enModId = HI_ID_PCIV;
                PcivMgr& pcivMgr = *PcivMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    PcivChip* pcivChip = NULL;
                    if (S_OK != pcivMgr.getChip(devName, &pcivChip))
                    {
                        printf("get pciv chip: %s failed!\n", devName.c_str());
                        break;
                    }

					id.s32DevId = 0;

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        PcivChn* pcivChn = NULL;
                        if (S_OK != pcivChip->getChn(chnName, &pcivChn))
                        {
                            printf("get pciv chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != pcivChn->getId(id.s32ChnId))
                        {
                            printf("get pciv chn: %s Id failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                    else
                        printf("src chnName not exist!\n");
                }
                else
                    printf("src devName not exist!\n");
            }
            else if (0 == modName.compare("vo"))
            {
                id.enModId = HI_ID_VO;
                VoMgr& voMgr = *VoMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    VoLayer* voLayer = NULL;
                    if (S_OK != voMgr.getLayer(devName, &voLayer))
                    {
                        printf("get vo layer: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != voLayer->getId(id.s32DevId))
                    {
                        printf("get vo layer: %s Id failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        VoChn* voChn = NULL;
                        if (S_OK != voLayer->getChn(chnName, &voChn))
                        {
                            printf("get vo chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != voChn->getId(id.s32ChnId))
                        {
                            printf("get vo chn: %s Id failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                    else
                        printf("dst chnName not exist!\n");
                }
                else
                    printf("dst devName not exist!\n");
            }
            else if (0 == modName.compare("venc"))
            {
                id.enModId = HI_ID_VENC;
                id.s32DevId = 0;        //venc has no grp or dev, default 0

                VencMgr& vencMgr = *VencMgr::instance();

                if (config.isMember("chnName") && config["chnName"].isString())
                {
                    const std::string& chnName = config["chnName"].asString();
                    VencChn* vencChn = NULL;
                    if (S_OK != vencMgr.getChn(chnName, &vencChn))
                    {
                        printf("get venc chn: %s failed!\n", chnName.c_str());
                        break;
                    }

                    if (S_OK != vencChn->getId(id.s32ChnId))
                    {
                        printf("get venc chn: %s Id failed!\n", chnName.c_str());
                        break;
                    }

                    ret = S_OK;
                }
                else
                    printf("dst chnName not exist!\n");
            }
            else if(0 == modName.compare("aenc"))
            {
                id.enModId = HI_ID_AENC;
                id.s32DevId = 0;        //aenc has no grp or dev, default 0

                AencMgr& aencMgr = *AencMgr::instance();

                if (config.isMember("chnName") && config["chnName"].isString())
                {
                    const std::string& chnName = config["chnName"].asString();
                    AencChn* aencChn = NULL;
                    if (S_OK != aencMgr.getChn(chnName, &aencChn))
                    {
                        printf("get aenc chn: %s failed!\n", chnName.c_str());
                        break;
                    }

                    if (S_OK != aencChn->getId(id.s32ChnId))
                    {
                        printf("get aenc chn: %s Id failed!\n", chnName.c_str());
                        break;
                    }

                    ret = S_OK;
                }
                else
                    printf("dst chnName not exist!\n");
            }
        }
        else
            printf("dst modName not exist!\n");
    }
    while(0);

    return ret;
}

S_Result SysCtrlMgrImp::startSrc(const Json::Value& config)
{
    Guard guard(fMutex);
    S_Result ret = S_ERROR;

    do
    {
        if (config.isMember("modName") && config["modName"].isString())
        {
            const std::string& modName = config["modName"].asString();
            if (0 == modName.compare("vi"))
            {
                ViMgr& viMgr = *ViMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    ViPipe* viPipe = NULL;
                    if (S_OK != viMgr.getPipe(devName, &viPipe))
                    {
                        printf("get vi pipe: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != viPipe->start())
                    {
                        printf("start vi pipe: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        ViChn* viChn = NULL;
                        if (S_OK != viPipe->getChn(chnName, &viChn))
                        {
                            printf("get vi chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != viChn->start())
                        {
                            printf("start vi chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                }
            }
            else if (0 == modName.compare("vpss"))
            {
                VpssMgr& vpssMgr = *VpssMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    VpssGrp* vpssGrp = NULL;
                    if (S_OK != vpssMgr.getGrp(devName, &vpssGrp))
                    {
                        printf("get vpss grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != vpssGrp->start())
                    {
                        printf("start vpss grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        VpssChn* vpssChn = NULL;
                        if (S_OK != vpssGrp->getChn(chnName, &vpssChn))
                        {
                            printf("get vpss chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != vpssChn->start())
                        {
                            printf("start vpss chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                }
            }
            else if (0 == modName.compare("avs"))
            {
                AvsMgr& avsMgr = *AvsMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    AvsGrp* avsGrp = NULL;
                    if (S_OK != avsMgr.getGrp(devName, &avsGrp))
                    {
                        printf("get avs grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != avsGrp->start())
                    {
                        printf("start avs grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        AvsChn* avsChn = NULL;
                        if (S_OK != avsGrp->getChn(chnName, &avsChn))
                        {
                            printf("get avs chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != avsChn->start())
                        {
                            printf("start avs chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                }
            }
            else if (0 == modName.compare("pciv"))
            {
                PcivMgr& pcivMgr = *PcivMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    PcivChip* pcivChip = NULL;
                    if (S_OK != pcivMgr.getChip(devName, &pcivChip))
                    {
                        printf("get pciv chip: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        PcivChn* pcivChn = NULL;
                        if (S_OK != pcivChip->getChn(chnName, &pcivChn))
                        {
                            printf("get pciv chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != pcivChn->start())
                        {
                            printf("start pciv chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                }
            }
            else if(0 == modName.compare("ai"))
            {
                AiMgr& aiMgr = *AiMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    AiDev* aiDev = NULL;
                    if (S_OK != aiMgr.getDev(devName, &aiDev))
                    {
                        printf("get ai dev: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (S_OK != aiDev->start())
                    {
                        printf("start ai dev: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        AiChn* aiChn = NULL;
                        if (S_OK != aiDev->getChn(chnName, &aiChn))
                        {
                            printf("get ai chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != aiChn->start())
                        {
                            printf("start ai chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                }
            }
        }
    }
    while(0);

    return ret;
}


S_Result SysCtrlMgrImp::stopSrc(const Json::Value& config)
{
    Guard guard(fMutex);
    S_Result ret = S_ERROR;

    do
    {
        if (config.isMember("modName") && config["modName"].isString())
        {
            const std::string& modName = config["modName"].asString();
            if (0 == modName.compare("vi"))
            {
                ViMgr& viMgr = *ViMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    ViPipe* viPipe = NULL;
                    if (S_OK != viMgr.getPipe(devName, &viPipe))
                    {
                        printf("get vi pipe: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        ViChn* viChn = NULL;
                        if (S_OK != viPipe->getChn(chnName, &viChn))
                        {
                            printf("get vi chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != viChn->stop())
                        {
                            printf("stop vi chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }

                    if (S_OK != viPipe->stop())
                    {
                        printf("stop vi pipe: %s failed!\n", devName.c_str());
                        break;
                    }
                }
            }
            else if (0 == modName.compare("vpss"))
            {
                VpssMgr& vpssMgr = *VpssMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    VpssGrp* vpssGrp = NULL;
                    if (S_OK != vpssMgr.getGrp(devName, &vpssGrp))
                    {
                        printf("get vpss grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        VpssChn* vpssChn = NULL;
                        if (S_OK != vpssGrp->getChn(chnName, &vpssChn))
                        {
                            printf("get vpss chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != vpssChn->stop())
                        {
                            printf("stop vpss chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }

                    if (S_OK != vpssGrp->stop())
                    {
                        printf("stop vpss grp: %s failed!\n", devName.c_str());
                        break;
                    }
                }
            }
            else if (0 == modName.compare("avs"))
            {
                AvsMgr& avsMgr = *AvsMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    AvsGrp* avsGrp = NULL;
                    if (S_OK != avsMgr.getGrp(devName, &avsGrp))
                    {
                        printf("get avs grp: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        AvsChn* avsChn = NULL;
                        if (S_OK != avsGrp->getChn(chnName, &avsChn))
                        {
                            printf("get avs chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != avsChn->stop())
                        {
                            printf("stop avs chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }

                    if (S_OK != avsGrp->stop())
                    {
                        printf("stop avs grp: %s failed!\n", devName.c_str());
                        break;
                    }
                }
            }
            else if (0 == modName.compare("pciv"))
            {
                PcivMgr& pcigMgr = *PcivMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    PcivChip* pcivChip = NULL;
                    if (S_OK != pcigMgr.getChip(devName, &pcivChip))
                    {
                        printf("get pciv chip: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        PcivChn* pcivChn = NULL;
                        if (S_OK != pcivChip->getChn(chnName, &pcivChn))
                        {
                            printf("get pciv chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != pcivChn->stop())
                        {
                            printf("stop pciv chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }
                }
            }
            else if(0 == modName.compare("ai"))
            {
                AiMgr& aiMgr = *AiMgr::instance();
                if (config.isMember("devName") && config["devName"].isString())
                {
                    const std::string& devName = config["devName"].asString();
                    AiDev* aiDev = NULL;
                    if (S_OK != aiMgr.getDev(devName, &aiDev))
                    {
                        printf("get ai dev: %s failed!\n", devName.c_str());
                        break;
                    }

                    if (config.isMember("chnName") && config["chnName"].isString())
                    {
                        const std::string& chnName = config["chnName"].asString();
                        AiChn* aiChn = NULL;
                        if (S_OK != aiDev->getChn(chnName, &aiChn))
                        {
                            printf("get ai chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        if (S_OK != aiChn->stop())
                        {
                            printf("stop ai chn: %s failed!\n", chnName.c_str());
                            break;
                        }

                        ret = S_OK;
                    }

                    if (S_OK != aiDev->stop())
                    {
                        printf("stop ai dev: %s failed!\n", devName.c_str());
                        break;
                    }
                }
            }
        }
    }
    while(0);

    return ret;
}

S_Result SysCtrlMgrImp::mmzAlloc_Cached(Uint64_t* pu64PhyAddr, void ** ppVirAddr,const char* pstrMmb, const char* pstrZone, Uint32_t u32Len)
{
  Guard guard(fMutex);
  HI_S32 s32Ret = HI_MPI_SYS_MmzAlloc_Cached(pu64PhyAddr,ppVirAddr,pstrMmb, pstrZone, u32Len);

  if (HI_SUCCESS != s32Ret)
      printf("HI_MPI_SYS_MmzAlloc_Cached failed! ret: %#x\n", s32Ret);

  return (HI_SUCCESS == s32Ret) ? S_OK : S_ERROR;
}

void* SysCtrlMgrImp::mMap(Uint64_t u64PhyAddr, Uint32_t u32Size)
{
    Guard guard(fMutex);
    HI_VOID *pstPhyAddr;

    pstPhyAddr = HI_MPI_SYS_Mmap(u64PhyAddr, u32Size);
    if(NULL == pstPhyAddr)
    {
        printf("HI_MPI_SYS_Mmap failed!\n");
        return NULL;
    }

   return pstPhyAddr;
}

S_Result SysCtrlMgrImp::mmUnMap(void  *  pVirAddr, Uint32_t u32Size)
{
  Guard guard(fMutex);
  HI_S32 s32Ret = HI_MPI_SYS_Munmap(pVirAddr, u32Size);
  printf("HI_MPI_SYS_Munmap ! ret: %#x\n", s32Ret);
  if (HI_SUCCESS != s32Ret)
  {
     printf("HI_MPI_SYS_Munmap failed! ret: %#x\n", s32Ret);
  }

  return (HI_SUCCESS == s32Ret) ? S_OK : S_ERROR;
}

Uint32_t  SysCtrlMgrImp::getBlock(Uint32_t    Pool,Uint64_t u64BlkSize,char* pcMmzName)
{
    Guard guard(fMutex);

     return HI_MPI_VB_GetBlock(Pool, u64BlkSize, pcMmzName);      
}

Int32_t SysCtrlMgrImp::releaseBlock(Uint32_t Block)
{
   Guard guard(fMutex);
   
    return HI_MPI_VB_ReleaseBlock(Block);   
}

Uint64_t SysCtrlMgrImp::handle2PhysAddr(Uint32_t Block)
{
    Guard guard(fMutex);
   
    return HI_MPI_VB_Handle2PhysAddr(Block);
}

}

